package org.javahispano.javacup.tacticas_aceptadas.jcrosas.chuky.futbolista;

import org.javahispano.javacup.modelo.Constantes;
import org.javahispano.javacup.tacticas_aceptadas.jcrosas.chuky.util.Balon;
import org.javahispano.javacup.tacticas_aceptadas.jcrosas.chuky.util.PosicionBalon;
import org.javahispano.javacup.tacticas_aceptadas.jcrosas.chuky.util.PosicionDespeje;
import org.javahispano.javacup.tacticas_aceptadas.jcrosas.chuky.util.PosicionFutura;

/**
 * @author Joan Crosas
 *
 */
public abstract class FutbolistaGenerico implements FutbolistaBase {

	
	@Override
	public boolean balonEncima( Balon balon ) {
		return balonEncima( balon.getPosicionBalon(), 0 );
	}
	
	@Override
	public boolean balonEncima( PosicionBalon posicionBalon, int t ) {
		double distanciaRecorrida = getVelocidad() * t;
		double distanciaBalon = posicionBalon.distancia( getPosicion() ) - distanciaRecorrida;
		double distanciaControl = ( isPortero() && (posicionBalon.isDentroArea() || posicionBalon.isDentroAreaRival() ))? 
				Constantes.DISTANCIA_CONTROL_BALON_PORTERO: Constantes.DISTANCIA_CONTROL_BALON;
				
		if( distanciaBalon <= distanciaControl && balonInterceptable( posicionBalon ) ) {
			return true;
		}
		return false;
	}

	@Override
	public double distanciaRecorrida( int tiempo ) {
		return getVelocidad() * tiempo;
	}

	@Override
	public PosicionFutura puedoInterceptar( Balon balon ) {
		int t = getIteracionesParaRematar() + 1;
		
		PosicionBalon posicionBalonFuturo = balon.getPosicionBalon( t );
		if( posicionBalonFuturo.distancia( getPosicion() ) > FutbolistaBase.DISTANCIA_MAX_VIGILAR_BALON ) {
			return null;
		}
		
		
		// mientras el bal�n esta dentro del radio de control del bal�n miramos si lo podemos interceptar 
		for( ; getPosicion().distancia( posicionBalonFuturo ) < FutbolistaBase.DISTANCIA_MAX_VIGILAR_BALON &&
				t <  FutbolistaBase.TIEMPO_MAX_CONTROL_BALON; 
				t++, posicionBalonFuturo = balon.getPosicionBalon( t ) ) {
			
			if( !posicionBalonFuturo.isDentroCampo() ) {
				return null;
			}
			if( balonEncima( posicionBalonFuturo, t ) ) {
				return new PosicionFutura( posicionBalonFuturo, t );
			}
			
		}
		return null;
	}
	
	@Override
	public PosicionFutura puedoInterceptarPase( Balon balon ) {
		int t = getIteracionesParaRematar() + 1;
		
		PosicionBalon posicionBalonFuturo = balon.getPosicionBalon( t );
		if( posicionBalonFuturo.distancia( getPosicion() ) > FutbolistaBase.DISTANCIA_MAX_PASE + 10 ) {
			return null;
		}
		
		
		// mientras el bal�n esta dentro del radio de control del bal�n miramos si lo podemos interceptar 
		for( ; getPosicion().distancia( posicionBalonFuturo ) < FutbolistaBase.DISTANCIA_MAX_PASE + 10 &&
				t <  FutbolistaBase.TIEMPO_MAX_PASE; 
				t++, posicionBalonFuturo = balon.getPosicionBalon( t ) ) {
			
			if( !posicionBalonFuturo.isDentroCampo() ) {
				return null;
			}
			if( balonEncima( posicionBalonFuturo, t ) ) {
				return new PosicionFutura( posicionBalonFuturo, t );
			}
			
		}
		return null;
	}

	@Override
	public PosicionFutura podreInterceptarPase( Balon balon, int tiempoAnticipacion, boolean autopase ) {
		int t = 1;
		
		if( autopase ) {
			t = Constantes.ITERACIONES_GOLPEAR_BALON + 1;
		}
		
		// primer comproba si el jugador esta dins de la distancia_max de pase
		PosicionBalon posicionBalonFuturo = balon.getPosicionBalon( t );
		if( posicionBalonFuturo.distancia( getPosicion() ) > FutbolistaBase.DISTANCIA_MAX_PASE ) {
			return null;
		}
		
		// mientras el bal�n esta dentro del radio de control del bal�n miramos si lo podemos interceptar 
		for( ; getPosicion().distancia( posicionBalonFuturo ) < FutbolistaBase.DISTANCIA_MAX_PASE &&
				t <  FutbolistaBase.TIEMPO_MAX_PASE; 
				t++, posicionBalonFuturo = balon.getPosicionBalon( t ) ) {
			
			if( !posicionBalonFuturo.isDentroCampo() ) {
				return null;
			}
			if( balonEncima( posicionBalonFuturo, t + tiempoAnticipacion ) ) {
				return new PosicionFutura( posicionBalonFuturo, t );
			}
			
		}
		return null;
		
	}
	
	@Override
	public PosicionDespeje podreInterceptarDespeje( Balon balon ) {
		int t = 1;
		
		// primer comproba si el jugador esta dins de la distancia_max de pase
		PosicionBalon posicionBalonFuturo = balon.getPosicionBalon( t );

		// mientras el bal�n esta dentro del radio de control del bal�n miramos si lo podemos interceptar 
		for( ; t < FutbolistaBase.TIEMPO_MAX_PASE; t++, posicionBalonFuturo = balon.getPosicionBalon( t ) ) {
			
			if( !posicionBalonFuturo.isDentroCampo() ) {
				double distancia = balon.getPosicionBalon().distancia( posicionBalonFuturo ) + 
					posicionBalonFuturo.distancia( FutbolistaBase.POSICION_PORTERIA );
				
				return new PosicionDespeje( posicionBalonFuturo, t, distancia, false );
			}
			if( balonEncima( posicionBalonFuturo, t ) ) {
				double distancia = balon.getPosicionBalon().distancia( posicionBalonFuturo ) + 
					posicionBalonFuturo.distancia( FutbolistaBase.POSICION_PORTERIA );
				
				return new PosicionDespeje( posicionBalonFuturo, t, distancia, true );
			}
			
		}
		double distancia = balon.getPosicionBalon().distancia( posicionBalonFuturo ) + 
				posicionBalonFuturo.distancia( FutbolistaBase.POSICION_PORTERIA );
		
		return new PosicionDespeje( posicionBalonFuturo, FutbolistaBase.TIEMPO_MAX_PASE, distancia, false );
	}
	
	@Override
	public boolean isPortero() {
		return ( getRol() == Rol.PORTERO )? true: false;
	}

	@Override
	public boolean balonInterceptable(PosicionBalon posicionBalon) {
		double alturaControlBalon = ( isPortero() && (posicionBalon.isDentroArea() || posicionBalon.isDentroAreaRival() ))? 
				Constantes.ALTO_ARCO: Constantes.ALTURA_CONTROL_BALON;
		
		if( posicionBalon.getAltura() <= alturaControlBalon && posicionBalon.isDentroCampo() ) {
			return true;
		}
		return false;
	}
	
	

}
